package com.dexter.year2023.charpter1_linkedlist.level2.topic2_4双指针;

import com.dexter.year2023.charpter1_linkedlist.level1.Demo1.Node;

import static com.dexter.year2023.charpter1_linkedlist.level1.Demo1.initLinkedList;
import static com.dexter.year2023.charpter1_linkedlist.level1.Demo1.printLinkedList;

/**
 * LeetCode 876. 链表的中间结点
 * https://leetcode.cn/problems/middle-of-the-linked-list/
 * <p>
 * 给你单链表的头结点 head ，请你找出并返回链表的中间结点。
 * 如果有两个中间结点，则返回第二个中间结点。
 * <p>
 * 示例 1：
 * 输入：head = [1,2,3,4,5]
 * 输出：[3,4,5]
 * 解释：链表只有一个中间结点，值为 3 。
 * 示例 2：
 * 输入：head = [1,2,3,4,5,6]
 * 输出：[4,5,6]
 * 解释：该链表有两个中间结点，值分别为 3 和 4 ，返回第二个结点。
 * <p>
 * 提示：
 * 链表的结点数范围是 [1, 100]
 * 1 <= Node.val <= 100
 *
 * @author Dexter
 */
public class Demo1MiddleNode {
    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4, 5};
        // int[] a = {1, 2, 3, 4, 5, 6};
        Node head = initLinkedList(a);
        // 本节方法，定义快慢指针
        head = middleNode(head);
        printLinkedList(head);
    }

    /**
     * 寻找中间结点，快指针走2步，慢指针走1步：
     * ▲ 奇数，fast.next == null，跳出，slow在中间位置
     * ■ 偶数，fast == null，跳出，slow在中间后一位位置
     *
     * @param head
     * @return
     */
    private static Node middleNode(Node head) {
        Node slow = head, fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
}
